package com.bjsdzk.common.security;

import com.bjsdzk.common.response.JSONResult;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.json.JSONObject;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * Created by zealdin on 2017/6/30.
 */
public class TokenAuthenticationService {
    static final long EXPIRATIONTIME = 31536000000l;     // 365天
    static final String SECRET = "P@ssw02d";            // JWT密码
    static final String TOKEN_PREFIX = "Bearer";        // Token前缀
    public static final String HEADER_STRING = "Authorization";// 存放Token的Header Key

    // JWT生成方法
    static void addAuthentication(HttpServletResponse response, String username) {

        long expirTime = EXPIRATIONTIME;
//        if (username.equals("demo")) {
//            expirTime = 24 * 60 * 60 * 1000;
//        }

        // 生成JWT
        String JWT = Jwts.builder()
                // 保存权限（角色）
                .claim("authorities", "ROLE_USER,ROLE_PLATFORM,ROLE_GOV,ROLE_ADMIN,ROLE_DEMO")
                // 用户名写入标题
                .setSubject(username)
                // 有效期设置
                .setExpiration(new Date(System.currentTimeMillis() + expirTime))
                // 签名设置
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .compact();

        // 将 JWT 写入 body
        try {
            response.setContentType("application/json");
            response.setStatus(HttpServletResponse.SC_OK);
            response.getOutputStream().println(JSONResult.fillResultString(0, "", JWT));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // JWT验证方法
    public static Authentication getAuthentication(HttpServletRequest request, HttpServletResponse response) {
        // 从Header中拿到token
        String token = request.getHeader(HEADER_STRING);

        try {
            if (token != null) {
                // 解析 Token
                Claims claims = Jwts.parser()
                        // 验签
                        .setSigningKey(SECRET)
                        // 去掉 Bearer
                        .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
                        .getBody();

                // 拿用户名
                String user = claims.getSubject();

                // 得到 权限（角色）
                List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get("authorities"));

                // 返回验证令牌
                return user != null ?
                        new UsernamePasswordAuthenticationToken(user, null, authorities) :
                        null;
            }
        } catch (ExpiredJwtException e) {
//            throw new AccountExpiredException("账号认证过期");
            response.setContentType("application/json; charset=UTF-8");
            response.setStatus(HttpServletResponse.SC_OK);
            response.setCharacterEncoding("UTF-8");
            response.setStatus(403);
            try {
                response.getOutputStream().write(JSONResult.fillResultString(403, "账号认证过期", JSONObject.NULL).getBytes("UTF-8"));
            } catch (IOException e1) {
            }
        }
        return null;
    }
}
